package com;

import com.jacob.activeX.ActiveXComponent;
import com.jacob.com.Dispatch;
import com.sun.speech.freetts.Voice;
import com.sun.speech.freetts.VoiceManager;
import org.eclipse.swt.ole.win32.Variant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.speech.Central;
import javax.speech.EngineException;
import javax.speech.synthesis.Synthesizer;
import javax.speech.synthesis.SynthesizerModeDesc;
import java.io.File;
import java.io.IOException;
import java.util.Locale;
import java.util.Objects;

public class ReadUtil {
    public static final String VOICE_ALAN = "alan";
    public static final String VOICE_KEVIN = "kevin";
    public static final String VOICE_KEVIN16 = "kevin16";

    private static final Voice VOICE = createVOice();

    private final static Logger LOGGER = LoggerFactory.getLogger(ReadUtil.class);

    public static boolean speeckMsg(String msg) {
        boolean flag = espeak(msg);
        if (Objects.equals(flag, Boolean.FALSE)) {
            flag = freeTTS(msg);
        }
        if (Objects.equals(flag, Boolean.FALSE)) {
            flag = jacob(msg);
        }
        return flag;
    }


    public static boolean espeak(String msg) {
        String text = "Hello, world!";

        try {
            // 调用 eSpeak 命令行接口
            ProcessBuilder pb = new ProcessBuilder("espeak", text);
            pb.start();
            return true;
        } catch (IOException e) {
            LOGGER.error("朗读失败", e);
        }
        return false;
    }

    public static boolean freeTTS(String msg) {
        try {
            if (Objects.nonNull(VOICE)) {
                VOICE.speak(msg);  // 将输入的语音转换为文字并输出
                return true;
            } else {
                System.err.println("Voice is null");
            }
        } catch (Exception e) {
            LOGGER.error("朗读失败", e);
        }

        return false;
    }

    public static boolean jacob(String msg) {
        File file = new File("jacob-1.18-x64.dll");
        System.load(file.getAbsolutePath());
        ActiveXComponent sap = new ActiveXComponent("Sapi.SpVoice");
        Dispatch sapo = sap.getObject();
        try {
            // 音量 0-100
            sap.setProperty("Volume", new com.jacob.com.Variant(100));
            // 语音朗读速度 -10 到 +10
            sap.setProperty("Rate", new com.jacob.com.Variant(0));
            // 执行朗读
            Dispatch.call(sapo, "Speak", new Variant(msg));
            return true;
        } catch (Exception e) {
            LOGGER.error("朗读失败", e);
        } finally {
            sapo.safeRelease();
            sap.safeRelease();
        }
        return false;
    }

    private static Voice createVOice() {
        System.setProperty("javax.speech.library.path", "freetts-jsapi10.jar");
        VoiceManager voiceManager = VoiceManager.getInstance();
        Voice voice = voiceManager.getVoice(VOICE_KEVIN16);

        if (voice == null) {
            voice = voiceManager.getVoice(VOICE_KEVIN);
            return voice;
        }

        if (voice == null) {
            voice = voiceManager.getVoice(VOICE_ALAN);
            return voice;
        }

        if (voice == null) {
            voice = voiceManager.getVoice(VOICE_ALAN);
            return voice;
        }

        if (voice == null) {
            voice = voiceManager.getVoice("cmu_time_awb");
            return voice;
        }

        if (voice == null) {
            voice = voiceManager.getVoice("time_awb");
            return voice;
        }

        if (voice == null) {
            voice = voiceManager.getVoice("awb");
            return voice;
        }
        if (voice == null) {
            voice = voiceManager.getVoice("en_us");
            return voice;
        }

        if (voice == null) {
            voice = voiceManager.getVoice("cmu_us_kal");
            return voice;
        }

        if (voice == null) {
            voice = VoiceManager.getInstance().getVoice("kevin");//Getting voice
            return voice;
        }


        System.setProperty("freetts.voices", "com.sun.speech.freetts.en.us.cmu_us_kal.KevinVoiceDirectory");

        if (voice == null) {
            voice = voiceManager.getVoice(VOICE_KEVIN);
            return voice;
        }

        if (voice == null) {
            voice = voiceManager.getVoice(VOICE_ALAN);
            return voice;
        }

        if (voice == null) {
            voice = voiceManager.getVoice(VOICE_ALAN);
            return voice;
        }

        javax.speech.synthesis.Voice voice1 = new javax.speech.synthesis.Voice();
        SynthesizerModeDesc desc = new SynthesizerModeDesc(Locale.US);
        try {
            Synthesizer synthesizer = Central.createSynthesizer(desc);
            if (Objects.nonNull(synthesizer)) {
                synthesizer.allocate();
            }
        } catch (EngineException e) {
            throw new RuntimeException(e);
        }
        return null;
    }

}
